#ifndef FF_PLUGIN_H
#define FF_PLUGIN_H

#include <array>
#include <ff_wrapper_gl.h>
#include <ff_wrapper_vk.h>

namespace FFSdkUnity {

class Plugin final {
public:
    Plugin() = default;
    Plugin(Plugin const &) = delete;
    Plugin &operator= (Plugin const &) = delete;
    Plugin(Plugin &&) = delete;
    Plugin &operator= (Plugin &&) = delete;
    ~Plugin() = default;

    void Init(IUnityInterfaces &interfaces) noexcept;
    void Destroy() noexcept;

    OpenGL::FFWrapperGL &GetWrapperGL() noexcept;
    Vulkan::FFWrapperVK &GetWrapperVK() noexcept;

private:
    using Callback = void (Plugin::*)();

    // Refer to IUnityGraphics.h, UnityGfxDeviceEventType.
    constexpr static size_t const CALLBACK_COUNT = 4U;

    bool AcquireGraphics(IUnityInterfaces &interfaces) noexcept;

    void RegisterCallbacks() noexcept;
    void UnregisterCallbacks() noexcept;

    void OnAfterReset() noexcept;
    void OnBeforeReset() noexcept;
    void OnInitialize() noexcept;
    void OnShutdown() noexcept;

    static void UNITY_INTERFACE_API OnDeviceEvent(UnityGfxDeviceEventType eventType);

    std::array<Callback, CALLBACK_COUNT> callbacks_{};
    OpenGL::FFWrapperGL ffWrapperGL_{};
    Vulkan::FFWrapperVK ffWrapperVK_{};
    IUnityGraphics *graphics_ = nullptr;
    IUnityInterfaces *interfaces_ = nullptr;

    static Plugin *instance_;
};

} // namespace FFSdkUnity

#endif // FF_PLUGIN_H
